package com.aaa.sso.service;

import com.aaa.common.bo.User;
import com.aaa.common.util.LoginUserInfo;
import com.aaa.common.util.Result;
import com.aaa.common.util.ResultStatus;
import com.aaa.sso.util.CustomUsernamePasswordToken;
import com.aaa.sso.util.LoginType;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service("userAuthService")
public class UserAuthServiceImpl implements AuthService {

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Result authUserMember(String userName, String password) {
        //收集用户信息
        AuthenticationToken usernamePasswordToken =
                new CustomUsernamePasswordToken(userName, password, LoginType.USER.toString());
        //获取主题 Subject 当前登录用户（shiro）
        Subject subject = SecurityUtils.getSubject();
        //实例化返回的map
        Map resultMap=new HashMap();
        //登录
        try {
            subject.login(usernamePasswordToken);
            //获取用户信息
            User user =(User) subject.getPrincipal();
            LoginUserInfo loginUserInfo=new LoginUserInfo();
            loginUserInfo.setLoginName(user.getLoginName());
            loginUserInfo.setHeadPic(user.getAvatar());
            loginUserInfo.setUserId(user.getUserId());

            //认证成功，生成token,   currentTimeMillis 1970年到现在的毫秒数
            String token = userName+System.currentTimeMillis();
            redisTemplate.delete(redisTemplate.keys(userName+"*"));
            //修改RedisTemplate的序列化策略
            RedisSerializer<String> stringSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringSerializer);
            //由于采用了String的序列化策略，所以只接受value值类型为String的参数。
            // 放入redis集群
            redisTemplate.opsForValue().set(token,user,60, TimeUnit.MINUTES);
            //返回信息
            resultMap.put("accessToken",token);
            resultMap.put("loginUserInfo",loginUserInfo);
            //记录登录日志

            return new Result(ResultStatus.SUCCESS.getCode(),
                    ResultStatus.SUCCESS.getMessage(),resultMap);
        }catch (AuthenticationException e){
            e.printStackTrace();
            resultMap.put("loginFail","用户名或者密码错误");
        }

        return new Result(ResultStatus.FAIL.getCode(),
                ResultStatus.FAIL.getMessage(),resultMap);
    }

    @Override
    public boolean checkToken(String accessToken) {
        return redisTemplate.hasKey(accessToken);
    }
}
